package com.heima.lock.sjms.工厂模式.手写ioc;

import jodd.io.findfile.ClassFinder;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 陈辉
 * @data 2024 14:22
 */

public class BeanFactory {
    private static Map<String,Object> springIOC;

    static {
        //1. 实例化ioc容器
        springIOC = new HashMap<>();
        //2. 开启包扫描，识别到带有Component注解的类
        //3. bean的实例化
        //4. ....
        //5. bean的装载
        String packageName = BeanFactory.class.getPackage().getName();
        String packagePath = packageName.replace('.', '/');
        URL packageURL = BeanFactory.class.getClassLoader().getResource(packagePath);

        if (packageURL != null) {
            try {
                File directory = new File(URLDecoder.decode(packageURL.getFile(), "UTF-8"));
                List<Class<?>> classes = findClasses(directory, packageName);

                for (Class<?> clazz : classes) {
                    //检测带有@Component注解的字节码，并实例化该类的对象
                    if (clazz.isAnnotationPresent(Component.class)){
                        Object bean = clazz.newInstance();
                        String beanName = clazz.getName();
                        beanName = beanName.substring(beanName.lastIndexOf(".")+ 1);
                        springIOC.put(beanName,bean);
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private static List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        if (!directory.exists()) {
            return classes;
        }
        File[] files = directory.listFiles();
        for (File file : files) {
            if (file.isFile() && file.getName().endsWith(".class")) {
                String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
                classes.add(Class.forName(className));
            }
        }
        return classes;
    }



    public static Object getBean(String beanName){
        return springIOC.get(beanName);
    }

}
